--[[ Script Start ]]
------------------------------------------ [[ 玩家自定义 ]] ------------------------------------------
userInfo = {
	-- 支持的枪械，排列顺序即是配置顺序
	-- 模式：0 - 不启用 | 1 - 启用 | 2 - 开启连点
	canUse = {
		["5.56"] = {
			-- 枪械             模式		下蹲系数
			{ "M416",           0,          0.75 },
			{ "Beryl M762",     1,          0.83 }, 
			{ "AKM",            0,          0.80 },
		},
		["7.62"] = {
			-- 枪械             模式         下蹲系数
			--{ "MINI",         0,          0.8 },
		},
		[".45"] = {
			-- 枪械             模式         下蹲系数
			{ "Micro UZI",      0,          0.8 }, 		-- 基础镜 + 扩容
		},
			-- 枪械             模式         下蹲系数
		["9mm"] = {
			{ "Vector",         0,          0.8 }, 		-- 基础镜 + 扩容
		},
	},

	-- 是否输出调试信息，关闭后可以减小 CPU 计算压力。建议调试时开启，调试完毕后关闭。(1 - 开启 | 0 - 关闭)
	-- (0 - Disable | 1 - Enable)
	debug = 0,

	-- CPU 负载等级，建议输入 1 ~ 30 之间的数字，不能小于 1 。值越小，压枪效果越好，值越大，帧数越高。(过分掉帧会直接影响压枪效果，请在保证帧数的情况下减小该值)
	cpuLoad = 2,

	-- 灵敏度调整 | Sensitivity adjustment
	sensitivity = {
		-- 肩射 | take aim
		Aim = 0.85,
		-- 消焰器
		scopeX0 = 1.09,
		--  裸配 | naked scope
		scopeX2 = 1.26,
		-- 三倍 | trebling scope
		scopeX3 = 3.0,
		-- 四倍 | quadruple scope
		scopeX4 = 4.0,
		-- 六倍 | sixfold scope
		scopeX6 = 6.0,
	},

	-- 启动控制 (capslock - 使用大写锁定键控制 | numlock - 小键盘锁定键控制 | scrolllock - 滚动键控制)
	startControl = "scrolllock",
	debugControl = "numlock",

	-- 瞄准设置 (default - 使用游戏默认设置 | recommend - 使用脚本推荐设置 | custom - 自定义设置 | ctrlmode - 下蹲模式) | Aiming setting
	aimingSettings = "ctrlmode",

	-- 当 aimingSettings = "custom" ，需要在此处设置自定义判断条件，通常配合 IsMouseButtonPressed 或 IsModifierPressed 使用
	customAimingSettings = {
		-- 开镜判断
		ADS = function ()
			return false -- 判断条件，返回值为布尔型
		end,
		-- 腰射判断
		Aim = function ()
			return false -- 判断条件，返回值为布尔型
		end,
	},

	-- G键自定义绑定，多余的组合键可以删除
	G_bind = {
		-- G
		["G5"] = "5.56",
		["G4"] = "7.62",
		["G7"] = "scopeX0",
		["G8"] = "scopeX1",
		["G9"] = "scopeX2",
	},
}

----------------------------- [[ 以下是脚本核心代码，非专业人士请勿改动 ]] -----------------------------
----------------------------- [[ 以下是脚本核心代码，非专业人士请勿改动 ]] -----------------------------
----------------------------- [[ 以下是脚本核心代码，非专业人士请勿改动 ]] -----------------------------

-- internal configuration
pubg = {
	gun = {
		[".45"] = {},
		["9mm"] = {},
		["5.56"] = {},
		["7.62"] = {},
	}, -- 枪械库
	gunOptions = {
		[".45"] = {},
		["9mm"] = {},
		["5.56"] = {},
		["7.62"] = {},
	}, -- 配置库
	allCanUse = {}, 		-- 所有可用枪械
	allCanUse_index = 1, 	-- 所有可用枪械列表索引
	allCanUse_count = 0, 	-- 所有可用总数量
	bulletType = "", 		-- 默认子弹型号
	gunIndex = 1,			-- 选中枪械下标
	counter = 0, 			-- 计数器
	xCounter = 0, 			-- x计数器
	sleep = userInfo.cpuLoad, -- 频率设置 (这里不能设置成0，调试会出BUG)
	sleepRandom = { userInfo.cpuLoad, userInfo.cpuLoad + 5 }, -- 防检测随机延迟
	startTime = 0, 	-- 鼠标按下时记录脚本运行时间戳
	prevTime = 0, 	-- 记录上一轮脚本运行时间戳
	scopeX1 = 1.0, 	-- 1倍压枪倍率 基瞄压枪倍率 (裸镜、红点、全息、侧瞄)
	scopeX0 = userInfo.sensitivity.scopeX0, 	-- 1.1倍压枪倍率
	scopeX2 = userInfo.sensitivity.scopeX2, 	-- 裸配
	scopeX3 = userInfo.sensitivity.scopeX3, 	-- 三倍压枪倍率
	scopeX4 = userInfo.sensitivity.scopeX4, 	-- 四倍压枪倍率
	scopeX6 = userInfo.sensitivity.scopeX6, 	-- 六倍压枪倍率

	scope_current = "scopeX1", 				-- 当前使用倍率
	G1 = false, 		-- G1键状态
	currentTime = 0, 	-- 此刻
	bulletIndex = 0, 	-- 第几颗子弹
}

pubg.xLengthForDebug = 30 -- 调试模式下的水平移动单元长度
-- 渲染节点
pubg.renderDom = {
	switchTable = "",
	separator = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", -- 分割线
	combo_key = "G-key", -- 组合键
	cmd = "cmd", -- 指令
	autoLog = "No operational data yet.\n", -- 压枪过程产生的数据输出
}

-- 是否开镜或瞄准
function pubg.isAimingState (mode)
	local switch = {
		-- 开镜
		["ADS"] = function ()
			if userInfo.aimingSettings == "recommend" then
				return IsMouseButtonPressed(3)-- and not IsModifierPressed("lshift")
			elseif userInfo.aimingSettings == "default" then
				return not IsModifierPressed("lshift") and not IsModifierPressed("lalt")
			elseif userInfo.aimingSettings == "ctrlmode" then
				return IsMouseButtonPressed(3)-- and not IsModifierPressed("lshift")
			elseif userInfo.aimingSettings == "custom" then
				return userInfo.customAimingSettings.ADS()
			end
		end,

		-- 腰射
		["Aim"] = function ()
			if userInfo.aimingSettings == "recommend" then
				return IsModifierPressed("lctrl")
			elseif userInfo.aimingSettings == "default" then
				return IsMouseButtonPressed(3)
			elseif userInfo.aimingSettings == "ctrlmode" then
				--return IsMouseButtonPressed(4) -- 按住下侧键时，肩射压枪
				return IsModifierPressed("lalt")
			elseif userInfo.aimingSettings == "custom" then
				return userInfo.customAimingSettings.Aim()
			end
		end,
	}

	return switch[mode]()
end

pubg["Beryl M762"] = function (gunName)

	return pubg.execOptions(gunName, {
		interval = 86,
		ballistic = {
			{1, 0},
			{2, 45},
			{4, 32},
			{8, 40},
			{12, 48},
			{16, 52},
			{20, 59},
			{24, 59},
			{28, 59},
			{32, 60},
			{36, 60},
			{40, 60},
			{42, 61},
		}
	})

end

pubg["M416"] = function (gunName)

	return pubg.execOptions(gunName, {
		interval = 86,
		ballistic = {
			{1, 0},
			{2, 36},
			{4, 16},
			{8, 30},
			{12, 34},
			{16, 36},
			{20, 40},
			{24, 42},
			{28, 42},
			{32, 43},
			{36, 43},
			{40, 44},
			{42, 44},
		}
	})

end

pubg["AKM"] = function (gunName)

	return pubg.execOptions(gunName, {
		interval = 100,
		ballistic = {
			{1, 0},
			{2, 45},
			{5, 25},
			{10, 35},
			{15, 48},
			{20, 56},
			{25, 61},
			{30, 59},
			{35, 59},
			{42, 59},
		}
	})

end

pubg["Vector"] = function (gunName)

	return pubg.execOptions(gunName, {
		interval = 55,
		ballistic = {
			{1, 0},
			{6, 16},
			{10, 20},
			{13, 24},
			{15, 28},
			{20, 32},
			{33, 34},
		}
	})

end

pubg["Micro UZI"] = function (gunName)

	return pubg.execOptions(gunName, {
		interval = 48,
		ballistic = {
			{1, 0},
			{2, 13},
			{10, 12},
			{15, 20},
			{35, 30},
		}
	})

end

-- [[通过枪械名查找在 canuse 中的项]]
function pubg.canUseFindByGunName (gunName)
	local forList = { "5.56", "7.62", ".45", "9mm" }
	for i = 1, #forList do
		local bulletType = forList[i]
		for j = 1, #userInfo.canUse[bulletType] do
			local item = userInfo.canUse[bulletType][j]
			if item[1] == gunName then
				return item
			end
		end
	end
end

--[[ FormatFactory ]]
function pubg.execOptions (gunName, options)
	--[[
		from
		{
			{ 1,  0},
			{ 5,  10 },
			{ 10, 24 },
		}
		to
		{ 0, 10, 10, 10, 10, 24, 24, 24, 24, 24 }
		to
		{ 0, 10, 20, 30, 40, 64, 88, 112, 136, 160 }
	]]

	local gunInfo = pubg.canUseFindByGunName(gunName)
	-- Temporary container
	local ballisticConfig1 = {}
	-- Temporary container (v3.0)
	local ballisticConfig2 = {}

	local ballisticIndex = 1
	for i = 1, #options.ballistic do
		local nextCount = options.ballistic[i][1]
		if i ~= 1 then
			nextCount = options.ballistic[i][1] - options.ballistic[i-1][1]
		end
		
		local value = options.ballistic[i][2]
		for j = 1, nextCount do
			-- 做简单的平滑处理
			if i > 3 then
				if j==1 then
					local value_s = math.floor((value + ballisticConfig1[ballisticIndex-1]) / 2)
					ballisticConfig1[ballisticIndex] = value_s
					ballisticConfig1[ballisticIndex-1] = value_s
				else
					value = options.ballistic[i][2]
					ballisticConfig1[ballisticIndex] = value
				end
			else
				ballisticConfig1[ballisticIndex] = value
			end
			ballisticIndex = ballisticIndex + 1
		end
	end

	for i = 1, #ballisticConfig1 do
		if i == 1 then
			ballisticConfig2[i] = ballisticConfig1[i]
		else
			ballisticConfig2[i] = ballisticConfig2[i-1] + ballisticConfig1[i]
		end
	end

	return {
		duration = options.interval * #ballisticConfig2, 	-- Time of duration
		amount = #ballisticConfig2, 						-- Number of bullets
		interval = options.interval, 						-- Time of each bullet
		ballistic = ballisticConfig2, 						-- ballistic data
		ctrlmodeRatio = gunInfo[3], 						-- 下蹲系数
	}

end

--[[ Initialization of firearms database ]]
function pubg.init ()
	-- Clean up the firearms Depot
	local forList = { "5.56", "7.62", ".45", "9mm" }
	for i = 1, #forList do
		local type = forList[i]
		local gunCount = 0

		for j = 1, #userInfo.canUse[type] do
			local gunName = userInfo.canUse[type][j][1]
			local gunState = userInfo.canUse[type][j][2]

			if gunState >= 1 then
				-- one series
				gunCount = gunCount + 1 -- Accumulative number of firearms configuration files
				pubg.gun[type][gunCount] = gunName -- Adding available firearms to the Arsenal
				pubg.gunOptions[type][gunCount] = pubg[gunName](gunName) -- Get firearms data and add it to the configuration library

				-- 单独设置连发
				pubg.gunOptions[type][gunCount].autoContinuousFiring = ({ 0, 0, 1 })[
					math.max(1, math.min(gunState + 1, 3))
				]
				-- all canUse
				pubg.allCanUse_count = pubg.allCanUse_count + 1 -- Total plus one
				pubg.allCanUse[pubg.allCanUse_count] = gunName -- All available firearms

				if pubg.bulletType == "" then pubg.bulletType = type end -- Default Bullet type
			end
		end
	end

	-- Initial setting of random number seeds
	pubg.SetRandomseed()
	pubg.outputLogRender()
end

-- SetRandomseed
function pubg.SetRandomseed ()
	math.randomseed(pubg.isEffective and GetRunningTime() or 0)
end

--[[ Before automatic press gun ]]
function pubg.auto (options)
	-- 第一颗子弹在按下鼠标的一瞬间已经射出，下面过程都是为第二颗及以后子弹压枪准备
	pubg.currentTime = GetRunningTime()
	local elapsedTime = pubg.currentTime - pubg.startTime
	pubg.bulletIndex = math.ceil((elapsedTime == 0 and 1 or elapsedTime) / options.interval) + 1
	if pubg.bulletIndex > options.amount then return false end
	
	-- 计算x应该位移的距离，Developer Debugging Mode
	local d = IsKeyLockOn("numlock") and (pubg.bulletIndex - 1) * pubg.xLengthForDebug or 0
	local x = math.floor(elapsedTime / (options.interval * (pubg.bulletIndex - 1)) * d) - pubg.xCounter

	-- 计算y应该位移的距离
	local curBulletAccDistance = pubg.getRealY(options, options.ballistic[pubg.bulletIndex])
	local prevBulletAccDistance = pubg.getRealY(options, options.ballistic[pubg.bulletIndex-1])
	local gapBulletAccDistance = curBulletAccDistance - prevBulletAccDistance
	local ratio = elapsedTime % options.interval / options.interval
	if elapsedTime % options.interval == 0 and elapsedTime > 0.5 * options.interval then
	    ratio = 1.0
	end
	local curBulletShift = ratio * gapBulletAccDistance
	local y = math.floor(curBulletShift + prevBulletAccDistance) - pubg.counter

	--local realY = pubg.getRealY(options, y)
	MoveMouseRelative(x, y)
	
	-- Whether to issue automatically or not
	if options.autoContinuousFiring == 1 then
		PressAndReleaseMouseButton(1)
	end

	-- Real-time operation parameters
	pubg.autoLog(options, y)
	--pubg.outputLogRender()

	pubg.xCounter = pubg.xCounter + x
	pubg.counter = pubg.counter + y

	pubg.autoSleep(IsKeyLockOn("numlock"))

end

--[[ get real y position ]]
function pubg.getRealY (options, y)
	local realY = y
	if pubg.isAimingState("ADS") then
		realY = y * pubg[pubg.scope_current]
	elseif pubg.isAimingState("Aim") then
		realY = y * userInfo.sensitivity.Aim
		realY = y * pubg[pubg.scope_current]
	else
		realY = 0
	end
	-- 下蹲按键为lctrl
	if userInfo.aimingSettings == "ctrlmode" and IsModifierPressed("lctrl") then
		realY = realY * options.ctrlmodeRatio
	end

	return realY
end

--[[ Sleep of pubg.auto ]]
function pubg.autoSleep (isTest)
	local random = 0
	if isTest then
		-- When debugging mode is turned on, Turn off random delays in preventive testing
		random = math.random(pubg.sleep, pubg.sleep)
	else
		random = math.random(pubg.sleepRandom[1], pubg.sleepRandom[2])
	end
	Sleep(random)
end

--[[ set bullet type ]]
function pubg.setBulletType (bulletType)
	pubg.bulletType = bulletType
	pubg.gunIndex = 1
	pubg.allCanUse_index = 0
	
	local forList = { "5.56", "7.62", ".45", "9mm" }
	for i = 1, #forList do
		local type = forList[i]
		if type ==  bulletType then
			pubg.allCanUse_index = pubg.allCanUse_index + 1
			break
		else
			pubg.allCanUse_index = pubg.allCanUse_index + #pubg.gun[type]
		end
	end
end

--[[ set current scope ]]
function pubg.setScope (scope)
	pubg.scope_current = scope
end

--[[ set current gun ]]
function pubg.setGun (gunName)

	local forList = { "5.56", "7.62", ".45", "9mm" }
	local allCanUse_index = 0

	for i = 1, #forList do
		local type = forList[i]
		local gunIndex = 0
		local selected = false

		for j = 1, #userInfo.canUse[type] do
			if userInfo.canUse[type][j][2] >= 1 then
				gunIndex = gunIndex + 1
				allCanUse_index = allCanUse_index + 1
				if userInfo.canUse[type][j][1] == gunName then
					pubg.bulletType = type
					pubg.gunIndex = gunIndex
					pubg.allCanUse_index = allCanUse_index
					selected = true
					break
				end
			end
		end

		if selected then break end

	end
end

--[[ Consider all available firearms as an entire list ]]
function pubg.findInCanUse (cmd)

	if "first_in_canUse" == cmd then
		pubg.allCanUse_index = 1
	elseif "next_in_canUse" == cmd then
		if pubg.allCanUse_index < #pubg.allCanUse then
			pubg.allCanUse_index = pubg.allCanUse_index + 1
		end
	elseif "last_in_canUse" == cmd then
		pubg.allCanUse_index = #pubg.allCanUse
	end

	pubg.setGun(pubg.allCanUse[pubg.allCanUse_index])
end

--[[ Switching guns in the same series ]]
function pubg.findInSeries (cmd)
	if "first" == cmd then
		pubg.gunIndex = 1
	elseif "next" == cmd then
		if pubg.gunIndex < #pubg.gun[pubg.bulletType] then
			pubg.gunIndex = pubg.gunIndex + 1
		end
	elseif "last" == cmd then
		pubg.gunIndex = #pubg.gun[pubg.bulletType]
	end

	pubg.setGun(pubg.gun[pubg.bulletType][pubg.gunIndex])
end

--[[ Script running status ]]
function pubg.runStatus ()
	if userInfo.startControl == "capslock" then
		return IsKeyLockOn("capslock")
	elseif userInfo.startControl == "numlock" then
		return IsKeyLockOn("numlock")
	elseif userInfo.startControl == "scrolllock" then
		return IsKeyLockOn("scrolllock")
	end
end

--[[ G key command binding ]]
function pubg.runCmd (cmd)
	if cmd == "" then cmd = "none" end
	local switch = {
		["none"] = function () end,
		[".45"] = pubg.setBulletType,
		["9mm"] = pubg.setBulletType,
		["5.56"] = pubg.setBulletType,
		["7.62"] = pubg.setBulletType,
		["scopeX0"] = pubg.setScope,
		["scopeX1"] = pubg.setScope,
		["scopeX2"] = pubg.setScope,
		["scopeX3"] = pubg.setScope,
		["scopeX4"] = pubg.setScope,
		["UMP45"] = pubg.setGun,
		["Tommy Gun"] = pubg.setGun,
		["Vector"] = pubg.setGun,
		["Micro UZI"] = pubg.setGun,
		["M416"] = pubg.setGun,
		["AKM"] = pubg.setGun,
		["Beryl M762"] = pubg.setGun,
		["first"] = pubg.findInSeries,
		["next"] = pubg.findInSeries,
		["last"] = pubg.findInSeries,
		["first_in_canUse"] = pubg.findInCanUse,
		["next_in_canUse"] = pubg.findInCanUse,
		["last_in_canUse"] = pubg.findInCanUse,
	}

	local cmdGroup = string.split(cmd, '|')
	for i = 1, #cmdGroup do
		local _cmd = cmdGroup[i]
		if switch[_cmd] then
			switch[_cmd](_cmd)
		end
	end
end

--[[ autputLog render ]]
function pubg.outputLogRender ()
	if userInfo.debug == 0 then return false end
	if not pubg.G1 then
		pubg.renderDom.switchTable = pubg.outputLogGunSwitchTable()
	end
	local resStr = table.concat({
		"\n>> [\"", pubg.renderDom.combo_key, "\"] = \"", pubg.renderDom.cmd, "\" <<\n",
		pubg.renderDom.separator,
		pubg.renderDom.switchTable,
		pubg.renderDom.separator,
		pubg.outputLogGunInfo(),
		pubg.renderDom.separator,
		pubg.renderDom.autoLog,
		pubg.renderDom.separator,
	})
	--ClearLog()
	OutputLogMessage(resStr)
end

--[[ Output switching table ]]
function pubg.outputLogGunSwitchTable ()
	local forList = { ".45", "9mm", "5.56", "7.62" }
	local allCount = 0
	local resStr = "      canUse_i\t      series_i\t      Series\t      ratio\t      ctrl ratio\t      Gun Name\n\n"

	for i = 1, #forList do
		local type = forList[i]
		local gunCount = 0

		for j = 1, #userInfo.canUse[type] do
			if userInfo.canUse[type][j][2] >= 1 then
				local gunName = userInfo.canUse[type][j][1]
				local tag = gunName == pubg.gun[pubg.bulletType][pubg.gunIndex] and "=> " or "      "
				gunCount = gunCount + 1
				allCount = allCount + 1
				resStr = table.concat({ resStr, tag, allCount, "\t", tag, gunCount, "\t", tag, type, "\t", tag, userInfo.canUse[type][j][3], "\t", tag, userInfo.canUse[type][j][4], "\t", tag, gunName, "\n" })
			end
		end

	end

	return resStr
end

-- output Log Gun Info
function pubg.outputLogGunInfo ()
	local k = pubg.bulletType
	local i = pubg.gunIndex
	local gunName = pubg.gun[k][i]

	return table.concat({
		"Currently scope: [ " .. pubg.scope_current .. " ]\n",
		"Currently series: [ ", k, " ]\n",
		"Currently index in series: [ ", i, " / ", #pubg.gun[k], " ]\n",
		"Currently index in canUse: [ ", pubg.allCanUse_index, " / ", pubg.allCanUse_count, " ]\n",
		"Recoil table of [ ", gunName, " ]:\n",
		pubg.outputLogRecoilTable(),
	})
end

--[[ output recoil table log ]]
function pubg.outputLogRecoilTable ()
	local k = pubg.bulletType
	local i = pubg.gunIndex
	local resStr = "{ "
	for j = 1, #pubg.gunOptions[k][i].ballistic do
		local num = pubg.gunOptions[k][i].ballistic[j]
		resStr = table.concat({ resStr, num })
		if j ~= #pubg.gunOptions[k][i].ballistic then
			resStr = table.concat({ resStr, ", " })
		end
	end

	resStr = table.concat({ resStr, " }\n" })

	return resStr
end

--[[ log of pubg.auto ]]
function pubg.autoLog (options, y)
	pubg.renderDom.autoLog = table.concat({
		"----------------------------------- Automatically counteracting gun recoil -----------------------------------\n",
		"------------------------------------------------------------------------------------------------------------------------------\n",
		"bullet index: ", pubg.bulletIndex, "    target counter: ", options.ballistic[pubg.bulletIndex], "    current counter: ", pubg.counter, "\n",
		"D-value(target - current): ", options.ballistic[pubg.bulletIndex], " - ", pubg.counter, " = ", options.ballistic[pubg.bulletIndex] - pubg.counter, "\n",
		"move: math.ceil((", pubg.currentTime, " - ", pubg.startTime, ") / (", options.interval, " * (", pubg.bulletIndex, " - 1)) * ", options.ballistic[pubg.bulletIndex], ") - ", pubg.counter, " = ", y, "\n",
		"------------------------------------------------------------------------------------------------------------------------------\n",
	})
end

-- return bool
function pubg.hasWeapon()
	local type = pubg.gunOptions[pubg.bulletType]
	return not (#type == 0)
end

--[[ Automatic press gun ]]
function pubg.OnEvent_NoRecoil (event, arg, family)
	if event == "MOUSE_BUTTON_PRESSED" and arg == 1 and family == "mouse" then
		if not pubg.runStatus() then return false end
		if not pubg.hasWeapon() then return end

		--if pubg.isAimingState("ADS") or pubg.isAimingState("Aim") then
			pubg.startTime = GetRunningTime()
			pubg.G1 = true
			SetMKeyState(1, "kb")
		--end
	end

	if event == "MOUSE_BUTTON_RELEASED" and arg == 1 and family == "mouse" then
		pubg.G1 = false
		pubg.counter = 0 -- Initialization counter
		pubg.xCounter = 0 -- Initialization xCounter
		pubg.SetRandomseed() -- Reset random number seeds
		-- 释放资源
		--ReleaseKey("lshift")
	end

	if event == "M_PRESSED" and arg == 1 and pubg.G1 and IsMouseButtonPressed(1) then
		pubg.auto(pubg.gunOptions[pubg.bulletType][pubg.gunIndex])
		SetMKeyState(1, "kb")
	end

	if event == "MOUSE_BUTTON_PRESSED" and arg == 2 and family == "mouse" then
		if not pubg.hasWeapon() then
			--PressKey("lshift")
		end
	end

	if event == "MOUSE_BUTTON_RELEASED" and arg == 2 and family == "mouse" then
		if not pubg.hasWeapon() then
			--ReleaseKey("lshift")
		end
	end

end

-- [[ processing instruction ]]
function pubg.modifierHandle (modifier)
	local cmd = userInfo.G_bind[modifier]
	pubg.renderDom.combo_key = modifier -- Save combination keys

	if (cmd) then
		pubg.renderDom.cmd = cmd -- Save instruction name
		pubg.runCmd(cmd) -- Execution instructions
	else
		pubg.renderDom.cmd = ""
	end

	pubg.outputLogRender() -- Call log rendering method to output information
end

--[[ Listener method ]]
function OnEvent (event, arg, family)
	pubg.OnEvent_NoRecoil(event, arg, family)

	if event == "MOUSE_BUTTON_PRESSED" and arg >=3 and arg <= 11 and family == "mouse" then
		local modifier = "G" .. arg
		local list = { "lalt", "lctrl", "lshift", "ralt", "rctrl", "rshift" }

		for i = 1, #list do
			if IsModifierPressed(list[i]) then
				modifier = list[i] .. " + " .. modifier
				break
			end
		end
		pubg.modifierHandle(modifier)

	elseif event == "G_PRESSED" and arg >=1 and arg <= 12 then
		-- if not pubg.runStatus() and userInfo.startControl ~= "G_bind" then return false end
		local modifier = "F" .. arg
		pubg.modifierHandle(modifier)
	end

	-- Script deactivated event
	if event == "PROFILE_DEACTIVATED" then
		EnablePrimaryMouseButtonEvents(false)
		ReleaseKey("lshift")
		ReleaseKey("lctrl")
		ReleaseKey("lalt")
		ReleaseKey("rshift")
		ReleaseKey("rctrl")
		ReleaseKey("ralt")
		ClearLog()
	end
end

--[[ tools ]]

-- split function
function string.split (str, s)
	if string.find(str, s) == nil then return { str } end

	local res = {}
	local reg = "(.-)" .. s .. "()"
	local index = 0
	local last_i

	--- @diagnostic disable-next-line: undefined-field
	for n, i in string.gfind(str, reg) do
		index = index + 1
		res[index] = n
		last_i = i
	end

	res[index + 1] = string.sub(str, last_i)

	return res
end

-- Javascript Array.prototype.reduce
function table.reduce (t, c)
	local res = c(t[1], t[2])
	for i = 3, #t do res = c(res, t[i]) end
	return res
end

-- Javascript Array.prototype.map
function table.map (t, c)
	local res = {}
	for i = 1, #t do res[i] = c(t[i], i) end
	return res
end

-- Javascript Array.prototype.forEach
function table.forEach (t, c)
	for i = 1, #t do c(t[i], i) end
end

--[[
	* 打印 table
	* @param  {any} val     传入值
	* @return {str}         格式化后的文本
]]
function table.print (val)

	local function loop (val, keyType, _indent)
		_indent = _indent or 1
		keyType = keyType or "string"
		local res = ""
		local indentStr = "     " -- 缩进空格
		local indent = string.rep(indentStr, _indent)
		local end_indent = string.rep(indentStr, _indent - 1)
		local putline = function (...)
			local arr = { res, ... }
			for i = 1, #arr do
				if type(arr[i]) ~= "string" then arr[i] = tostring(arr[i]) end
			end
			res = table.concat(arr)
		end

		if type(val) == "table" then
			putline("{ ")

			if #val > 0 then
				local index = 0
				local block = false

				for i = 1, #val do
					local n = val[i]
					if type(n) == "table" or type(n) == "function" then
						block = true
						break
					end
				end

				if block then
					for i = 1, #val do
						local n = val[i]
						index = index + 1
						if index == 1 then putline("\n") end
						putline(indent, loop(n, type(i), _indent + 1), "\n")
						if index == #val then putline(end_indent) end
					end
				else
					for i = 1, #val do
						local n = val[i]
						index = index + 1
						putline(loop(n, type(i), _indent + 1))
					end
				end

			else
				putline("\n")
				for k, v in pairs(val) do
					putline(indent, k, " = ", loop(v, type(k), _indent + 1), "\n")
				end
				putline(end_indent)
			end

			putline("}, ")
		elseif type(val) == "string" then
			val = string.gsub(val, "\a", "\\a") -- 响铃(BEL)
			val = string.gsub(val, "\b", "\\b") -- 退格(BS),将当前位置移到前一列
			val = string.gsub(val, "\f", "\\f") -- 换页(FF),将当前位置移到下页开头
			val = string.gsub(val, "\n", "\\n") -- 换行(LF),将当前位置移到下一行开头
			val = string.gsub(val, "\r", "\\r") -- 回车(CR),将当前位置移到本行开头
			val = string.gsub(val, "\t", "\\t") -- 水平指标(HT),(调用下一个TAB位置)
			val = string.gsub(val, "\v", "\\v") -- 垂直指标(VT)
			putline("\"", val, "\", ")
		elseif type(val) == "boolean" then
			putline(val and "true, " or "false, ")
		elseif type(val) == "function" then
			putline(tostring(val), ", ")
		elseif type(val) == "nil" then
			putline("nil, ")
		else
			putline(val, ", ")
		end

		return res
	end

	local res = loop(val)
	res = string.gsub(res, ",(%s*})", "%1")
	res = string.gsub(res, ",(%s*)$", "%1")
	res = string.gsub(res, "{%s+}", "{}")

	return res
end

-- console
console = {}
function console.log (str)
	OutputLogMessage(table.print(str) .. "\n")
end

--[[ Other ]]
EnablePrimaryMouseButtonEvents(true) -- Enable left mouse button event reporting
pubg.GD = GetDate -- Setting aliases
pubg.init() -- Script initialization

--[[ Script End ]]